#!/usr/bin/python
#-*- coding: utf-8 -*-
"""OBJ Parser Pascal, soll indexe Faceset als Liste bereitstellen [ [x1, y1, z1, xvt1, yvt1, zvt1, xvn1, yvn1, zvn1], ... ]noch nicht ganz ok =) """
import sys

VERTICES='vertices'
VERTEX_TEXTURES='vertex_textures'
VERTEX_NORMS='vertex_norms'
FACES='faces'
BLANK=[]

def get_value(index, lis # [ [x1,y1,z1], [x2,y2,z2], ... ]
              ):
    """Gibt 3D Koordinate anhand des Index aus zugehoeriger Liste zurueck"""
    coordinate = [v for v in lis[index-1]] # indizierung beginnt bei 1 bei indexed facesets
    return coordinate    
# TODO:
def get_faces_coordinates(**faceset_dict # Dictionary mit Listen welche die Koordinatenwerte enthalten
                          ):
    """Return Liste von Faces mit Punktkoordinaten anstelle von Indizes"""
    # nimm jede face liste, davon jeden string  # [['1//2', '3/4/6', '4//5'], ...]
    # splitte den string in 3 teile bei // nur 2 elemnte , bei keinem / nur vertices bei / 3 teile
    # assert [[1,None,3], [...] ]
    # erstelle funktion die index und liste erwartet das index -1 ste element zurueckgibt oder None bei None
    # fuege der ret liste listen. fuer jeden index wird funktion aufgerufen

    if faceset_dict=={}:
        raise AttributeError, 'Keine Facesets uebergeben.'
    
    faces_strings = faceset_dict[FACES]
    vertices = faceset_dict[VERTICES]
    textures = faceset_dict[VERTEX_TEXTURES]
    norms = faceset_dict[VERTEX_NORMS]
    
    # faceliste mit Indizes aus Strings zu ints konvertieren 
    faces_indices = []
    for face_string in faces_strings:
        face = []
        for value_string in face_string:
            if '//' in value_string: # v//vn
                face_indices = map(int, value_string.split('//'))
                face_indices.insert(1,BLANK)
                face.append(face_indices)                
            elif '/' in value_string: # v/vt/vn
                face.append(map(int, value_string.split('/')))                
            else: # v
                face.append([int(value_string), BLANK, BLANK])        
        faces_indices.append(face)
    
    # assert faces_indices == [ [[1,None,3], [a,b,c], [a,b,c]] ]
    
    # werte zu den indizes aus entsprechender liste herausholen
    ret = []    
    for face in faces_indices: # [ [[1,None,3], [a,b,c], [a,b,c]] ]        
        for face_values in face: # [a,b,c]            
            v, vt, vn = face_values[0], face_values[1], face_values[2]            
            val_v = get_value(v, vertices)
            val_vt = BLANK if vt==BLANK else get_value(vt, textures)
            val_vn = BLANK if vn==BLANK else get_value(vn, norms)
            face_values.append([val_v, val_vt, val_vn])
        ret.append(face_values)
    return ret            

def read_and_sort_obj_content(obj_file):
    """Return Dictionary mit Listen von Indizierten Vertices, Texturen und Normalen sowie Liste der faces mit Indizes"""
    lines = [line.split() for line in file(obj_file)]
    # [ [a,b,c], [a,b,c], ...]
    
    vertices = []
    vertex_textures = []
    vertex_norms = []
    faces = []

    for line in lines:
        if line: # Leerzeilen nicht bearbeiten 
            if line[0] == 'v':
                vertices.append(map(float, line[1:]))
            if line[0] == 'vt':
                vertex_textures.append(map(float, line[1:]))
            if line[0] == 'vn':
                vertex_norms.append(map(float, line[1:]))
            if line[0] == 'f':
                faces.append(line[1:])
    return {VERTICES:vertices, VERTEX_TEXTURES:vertex_textures, VERTEX_NORMS:vertex_norms, FACES:faces}

def init_geometry_from_obj_file(obj_file):
    """Gibt Tupel von Punktlisten zurueck die OpenGL/VBO benoetigt"""
    faceset_dict = read_and_sort_obj_content(obj_file)
    faces_coordinates = get_faces_coordinates(**faceset_dict)
    return faces_coordinates
    
def main():
    f_name = 'test.obj'
    geo_list = init_geometry_from_obj_file(f_name)  
    print geo_list[:1],  ' punkt-infos 1. punkt', 
    
if __name__=='__main__':
    main()
